// @ts-nocheck
/**
 * 队列操作
 * @param concurrency 同时执行的数量
 * @param fn 操作函数 异步函数
 * @param fn.dataItem 操作的数据
 * @param fn.getRemoveQueue 撤销排队中的某一个任务
 * @returns {function(*=, *=): Promise<unknown>}
 * 使用方法
 * let removeFn = null
 * const getRemoveFn = fn => removeFn = fn
 * const handleDataByQueue = createQueue(3, async (dataItem) => {
 *  await sleep(1000)
 *  console.log(dataItem)
 *  return dataItem
 *  })
 *  handleDataByQueue(1, getRemoveFn)
 *  // 取消排队
 *  setTimeout(() => {
 *  removeFn && removeFn()
 *  }, 1000)
 * */
export const createQueue = (concurrency, fn) => {
  const queue = []
  const runningQueue = []
  // 撤销排队中的某一个任务
  const removeQueue = task => {
    const index = queue.findIndex(item => item === task)
    if (index !== -1) {
      console.log('取消排队')
      queue.splice(index, 1)
    }
  }
  const process = (dataItem, getRemoveQueue) => {
    return new Promise((resolve, reject) => {
      const run = async () => {
        if (runningQueue.length >= concurrency) {
          queue.push(run)
          getRemoveQueue && getRemoveQueue(() => removeQueue(run))
          return
        }
        runningQueue.push(run)
        try {
          const result = await fn(dataItem)
          resolve(result)
        } catch (e) {
          reject(e)
        } finally {
          runningQueue.splice(runningQueue.indexOf(run), 1)
          if (queue.length) {
            queue.shift()()
          }
        }
      }
      return run()
    })
  }
  return process
}
export const getFilesFromDataTransferItemList = async (items, fileCall: (file, webkitRelativePath: string) => void) => {
  const dfsForDirectory = async item => {
    if (item.isFile) {
      // 文件
      const file = await readFileEntrieQueue(item)
      // 把路径存放进来 无法设置进去
      // file.webkitRelativePath = (item.fullPath as string).substring(1)
      // 这里处理文件
      fileCall(file, (item.fullPath as string).substring(1))
    } else {
      //  文件夹
      // 获取文件夹中的文件entry
      const entries = await readDirEntrieQueue(item)
      for (let entry of entries) {
        // 递归获取文件
        await dfsForDirectory(entry)
      }
    }
  }
  for (let i = 0; i < items.length; i++) {
    // webkitGetAsEntry()方法返回一个FileSystemEntry对象，表示DataTransferItem对象的文件系统条目
    await dfsForDirectory(items[i].webkitGetAsEntry())
  }
}
const readDirEntrieQueue = createQueue(20, entery => {
  return new Promise((resolve, reject) => {
    // 读取文件夹,返回一个FileSystemDirectoryReader对象,该对象表示一个目录的内容,可以通过readEntries()方法读取目录的内容
    entery.createReader().readEntries(entries => {
      resolve(entries)
    })
  })
})
const readFileEntrieQueue = createQueue(20, entery => {
  // 读取文件
  return new Promise((resolve, reject) => {
    entery.file(file => {
      resolve(file)
    })
  })
})

